﻿using System;
using System.Collections.Generic;

namespace Lukianol.Web.Report
{
    public class SqlReportFormatInfoFactory
    {
        public const string Image = "IMAGE";
        public const string Mhtml = "MHTML";
        public const string Pdf = "PDF";
        public const string Word = "WORD";
        public const string Excel = "EXCEL";
        public const string Csv = "CSV";
        public const string Xml = "XML";
        public const string Html4 = "HTML4.0";


        private static readonly object Locker = new object();
        private static SqlReportFormatInfoFactory _current;
        public static SqlReportFormatInfoFactory Current
        {
            get
            {
                if (_current != null)
                    return _current;

                lock(Locker)
                {
                    return _current ?? (_current = new SqlReportFormatInfoFactory());
                }
            }
        }
       
        public IReportFormatInfoProvider GetInstance(string format)
        {
            if (format == null) throw new ArgumentNullException("format");

            format = format.ToUpperInvariant();

            return _providers.ContainsKey(format) 
                       ? _providers[format] 
                       : new OtherFormatInfoProvider(format);
        }

        private SqlReportFormatInfoFactory()
        {
            Add(new XmlReportFormatInfoProvider());
            Add(new CsvReportFormatInfoProvider());
            Add(new ExcelReportFormatInfoProvider());
            Add(new WordReportFormatInfoProvider());
            Add(new PdfReportFormatInfoProvider());
            Add(new MhtmlReportFormatInfoProvider());
            Add(new TiffReportFormatInfoProvider());
            Add(new Html4ReportFormatInfoProvider());
        }

        void Add(IReportFormatInfoProvider provider)
        {
            _providers.Add(provider.Name.ToUpperInvariant(), provider);
        }

        private readonly IDictionary<string, IReportFormatInfoProvider> _providers = new Dictionary<string, IReportFormatInfoProvider>();

        public class Html4ReportFormatInfoProvider : ReportFormatInfoProvider
        {
            public Html4ReportFormatInfoProvider()
                : base(Html4)
            {

            }

            public int PageNumber { get; set; }

            public override IEnumerable<KeyValuePair<string, string>> GetParameters()
            {
                yield return new KeyValuePair<string, string>("HtmlFragment", "True");
                yield return new KeyValuePair<string, string>("JavaScript", "False");
                yield return new KeyValuePair<string, string>("Section", PageNumber.ToString());
            }

            public override string ContentType
            {
                get { return "text/html"; }
            }

            public override string FileExtension
            {
                get { return "html"; }
            }
        }

        class OtherFormatInfoProvider : ReportFormatInfoProvider
        {
            public OtherFormatInfoProvider(string name)
                : base(name)
            {

            }

            public override string ContentType
            {
                get { return "text/plain"; }
            }

            public override string FileExtension
            {
                get { return null; }
            }
        }

        class TiffReportFormatInfoProvider : ReportFormatInfoProvider
        {
            public TiffReportFormatInfoProvider()
                : base(Image)
            {
            }

            public override string ContentType
            {
                get { return "image/tiff"; }
            }

            public override string FileExtension
            {
                get { return "tiff"; }
            }
        }

        class MhtmlReportFormatInfoProvider : ReportFormatInfoProvider
        {
            public MhtmlReportFormatInfoProvider()
                : base(Mhtml)
            {
            }

            public override string ContentType
            {
                get { return "multipart/related"; }
            }

            public override string FileExtension
            {
                get { return "mht"; }
            }
        }

        class PdfReportFormatInfoProvider : ReportFormatInfoProvider
        {
            public PdfReportFormatInfoProvider()
                : base(Pdf)
            {
            }

            public override string ContentType
            {
                get { return "application/pdf"; }
            }

            public override string FileExtension
            {
                get { return "pdf"; }
            }
        }

        class WordReportFormatInfoProvider : ReportFormatInfoProvider
        {
            public WordReportFormatInfoProvider()
                : base(Word)
            {
            }

            public override string ContentType
            {
                get { return "application/vnd.ms-word"; }
            }

            public override string FileExtension
            {
                get { return "doc"; }
            }
        }

        class ExcelReportFormatInfoProvider : ReportFormatInfoProvider
        {
            public ExcelReportFormatInfoProvider()
                : base(Excel)
            {
            }

            public override string ContentType
            {
                get { return "application/vnd.ms-excel"; }
            }

            public override string FileExtension
            {
                get { return "xls"; }
            }
        }

        class CsvReportFormatInfoProvider : ReportFormatInfoProvider
        {
            public CsvReportFormatInfoProvider()
                : base(Csv)
            {

            }

            public override string ContentType
            {
                get { return "text/csv"; }
            }

            public override string FileExtension
            {
                get { return "csv"; }
            }
        }

        class XmlReportFormatInfoProvider : ReportFormatInfoProvider
        {
            public XmlReportFormatInfoProvider()
                : base(Xml)
            {
            }

            public override string ContentType
            {
                get { return "text/xml"; }
            }

            public override string FileExtension
            {
                get { return "xml"; }
            }
        }

    }

}